﻿<###################################################################################################################################
 # SSRS_Tools.ps1 #>Set-StrictMode -Version Latest;
<##################################################################################################################################>
function Publish-SSRS {<#
.SYNOPSIS
	Deploy SSRS reports (RDL) & data sources (RDS).

.DESCRIPTION
	Deploys any number of SSRS reports and/or data sources to a reporting server. The list of reports or data sources
	is contained within CSV files whose paths are passed as optional parameters. Does not read from the .rptproj file.
	Useful when a subset of reports needs to be deployed to multiple servers.

.PARAMETER ReportServer
	Full URI of the Reporting Services server in the form "http://sqlnerd.me/ReportServer" (^https?://).

.PARAMETER Manifest
	CSV file listing the report elements to be deployed.

.EXAMPLE
	Deploy-SSRS -ReportServer http://sqlnerd.me/ReportServer -Manifest .\SSRS_Project.csv;	
	

.EXAMPLE
	Get-Content ServerList.txt | Deploy-SSRS -Definitions .\Definitions.CSV;

	Description
	-----------
	This command pipes the content of the ServerList.txt file to Deploy-SSRS. The report definitions in
	Definitions.CSV are deployed to each URI in ServerList.txt. No data sources are deployed.

.EXAMPLE
	Deploy-SSRS

#>[CmdletBinding()] Param (    [Parameter ( Mandatory= $True, ValueFromPipeline=$True, ValueFromPipelinebyPropertyName=$True )]        [string[]] [ValidatePattern('^https?://')]        $ReportServerURL,    [Parameter ( Mandatory= $True )]        [string]        $Manifest);    BEGIN {$Items= (Import-Csv $Manifest)};    PROCESS {$ReportServerURL | % {        Write-Output "`n$($_)";        $SSRSProxy= New-WebServiceProxy -Uri "$_/ReportService2010.asmx?WSDL" -UseDefaultCredential -Namespace "SSRS";        $DataType= "$($SSRSProxy.GetType().Namespace).Property";        foreach ($Item in ($Items | Where-Object {$_.Include -eq 1}) ) {            Write-Output "	$($Item.Type)	$($Item.Parent)/$($Item.Name)	$($Item.MimeType)";            $Warnings= $Properties= $Description= $Hidden= $MimeType= $null;            try {$SSRSProxy.CreateFolder($($Item.Parent).Substring(1), "/", $null)} catch {};	# folder may already exist            switch ($Item.Type) {                "DataSource"	{                    # read the RDS file (XML) directly and build the DataSourceDefinition object from that info                    [xml]$DataSourceXML= Get-Content $Item.Definition;                    $ConnectionProperties= $DataSourceXML.RptDataSource.ConnectionProperties;                    $Definition= New-Object -TypeName SSRS.ReportingService2010.DataSourceDefinition;                    $Definition.ConnectString= $ConnectionProperties.ConnectString;                    $Definition.Extension= $ConnectionProperties.Extension ;                    if ([Convert]::ToBoolean($ConnectionProperties.IntegratedSecurity)) {$Definition.CredentialRetrieval= 'Integrated';};                    $Results= $SSRSProxy.CreateDataSource($Item.Name, $Item.Parent, [Convert]::ToBoolean($True), $Definition, $null);                };                "Resource"	{                    $Description= New-Object -TypeName $DataType;
                    $Description.Name= "Description"; $Description.Value= "";
                    $Hidden= New-Object -TypeName $DataType;
                    $Hidden.Name= "Hidden"; $Hidden.Value= $false;
                    $MimeType= New-Object -TypeName $DataType;
                    $MimeType.Name= "MimeType"; $MimeType.Value= $($Item.MIMEType);
                    $Properties= @($Description, $Hidden, $MimeType);                    $Definition= Get-Content -Encoding Byte -Path $Item.Definition;                    $Results= $SSRSProxy.CreateCatalogItem("Resource", $Item.Name, $Item.Parent, $True, $Definition, $Properties, [ref]$Warnings);                };                "Report"	{                    $Properties= $null;                    $Definition= Get-Content -Encoding Byte -Path $Item.Definition;                    $Results= $SSRSProxy.CreateCatalogItem("Report", $Item.Name, $Item.Parent, $True, $Definition, $Properties, [ref]$Warnings);                };                default	{Write-Error "Unknown Item Type"};            };            if ($Warnings -ne $null) {$Warnings | Where-Object Code -NotIn "rsDataSourceReferenceNotPublished","rsOverlappingReportItems" | ForEach-Object {Write-Warning $_.Message}; $Warnings= $null};        }; # foreach ($Item in $Items)        $SSRSProxy.Dispose();        $SSRSProxy= $null;    }};    END {Write-Host "`nCOMPLETE"};};<##################################################################################################################################>
Write-Verbose "SSRS_Tools Loaded";